package com.example.springboot01.controller;


import com.example.springboot01.DTO.AccountDTO;
import com.example.springboot01.annotation.Permissions;
import com.example.springboot01.annotation.WithoutAuthorization;
import com.example.springboot01.config.ResultMsg;
import com.example.springboot01.config.ResultStatusEnum;
import com.example.springboot01.config.ServiceException;
import com.example.springboot01.model.Account;
import com.example.springboot01.params.AccountParams;
import com.example.springboot01.service.AccountService;
import com.example.springboot01.service.TokenManageService;
import com.example.springboot01.utils.ModelMapperUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author ruanzhihong
 * @since 2022-05-08
 */
@Api(value = "Account",tags = "账户管理(普通)")
@RestController
@RequestMapping("/account")
public class AccountController {

    @Autowired
    AccountService accountService;
    @Autowired
    TokenManageService tokenManageService;

    Logger logger = LoggerFactory.getLogger(getClass());


    /**
     * @param accountParams 账户参数
     * @return 返回结果
     */
    @ApiOperation(value = "账户注册", notes = "根据账户参数创建一个账户记录")
    @WithoutAuthorization
    @ApiImplicitParam(name = "accountParams", value = "账户参数", required = true, dataType = "AccountParams")
    @PostMapping("/")
    public ResultMsg register(AccountParams accountParams) {
        try {
            //非空校验
            if (StringUtils.isBlank(accountParams.getUserName())) {
                return ResultMsg.error(ResultStatusEnum.SAVE_ERROR, "账户姓名存在空值");
            }
            if (StringUtils.isBlank(accountParams.getPassword())) {
                return ResultMsg.error(ResultStatusEnum.SAVE_ERROR, "账户密码存在空值");
            }
            if (StringUtils.isBlank(accountParams.getNickName())) {
                return ResultMsg.error(ResultStatusEnum.SAVE_ERROR, "账户昵称存在空值");
            }
            if (StringUtils.isBlank(accountParams.getGender())) {
                return ResultMsg.error(ResultStatusEnum.SAVE_ERROR, "账户性别存在空值");
            }
            if (StringUtils.isBlank(accountParams.getEmail())) {
                return ResultMsg.error(ResultStatusEnum.SAVE_ERROR, "账户邮箱存在空值");
            }
            if (StringUtils.isBlank(accountParams.getTelephone())) {
                return ResultMsg.error(ResultStatusEnum.SAVE_ERROR, "账户手机号码存在空值");
            }
            //参数类转实体类
            Account account = paramsToBean(accountParams);
            //调用服务层方法做保存
            accountService.save(account);
            //操作结果返回
            return ResultMsg.ok(ResultStatusEnum.SAVE_SUCCESS);

        } catch (ServiceException se) {
            logger.error("注册失败：" + se.getMsg());
            return ResultMsg.error(ResultStatusEnum.SAVE_ERROR, se.getMsg());
        } catch (Exception e) {
            logger.error(ExceptionUtils.getStackTrace(e));
            return ResultMsg.error(ResultStatusEnum.SAVE_ERROR);
        }
    }

    /**
     * 参数类转实体类
     *
     * @param accountParams 账户参数类对象
     * @return 实体类对象
     */
    private Account paramsToBean(AccountParams accountParams) {
        Account account = ModelMapperUtils.map(accountParams, Account.class);
        return account;
    }

    /**
     * 账户修改
     *
     * @param token            账户token
     * @param accountParams 账户参数
     * @return 返回结果
     */
    @ApiOperation(value = "账户编辑", notes = "根据账户id和账户属性更新账户记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token",value = "token字符串",required = true,dataType = "String",paramType = "header"),
            @ApiImplicitParam(name = "accountParams", value = "账户参数", required = true, dataType = "AccountParams")
    })
    @PutMapping("/")
    public ResultMsg update(@RequestHeader String token, @RequestBody AccountParams accountParams) {
        try {
            //从token中解析账户id
            String id = tokenManageService.getUserIdFromToken(token);
            if(StringUtils.isEmpty(id)){
                logger.error("token解析出的账户id为空，token:" + token);
                return ResultMsg.error(ResultStatusEnum.UPDATE_SUCCESS);
            }
            //参数类转实体类
            Account account = paramsToBean(accountParams);
            account.setId(id);
            account.setPassword(null);
            //调用服务层对象来更新用户
            accountService.updateById(account);
            //返回操作结果
            return ResultMsg.ok(ResultStatusEnum.UPDATE_SUCCESS);

        } catch (ServiceException se) {
            logger.error("账户编辑失败：" + se.getMsg());
            return ResultMsg.error(ResultStatusEnum.UPDATE_ERROR, se.getMsg());
        } catch (Exception e) {
            logger.error(ExceptionUtils.getStackTrace(e));
            return ResultMsg.error(ResultStatusEnum.UPDATE_ERROR);
        }
    }

    /**
     * 获取账户信息
     *
     * @param token
     * @return 账户Dto
     */

    @ApiOperation(value = "获取账户", notes = "根据账户id获取账户信息")
    @ApiImplicitParam(name = "token",value = "token字符串",required = true,dataType = "String",paramType = "header")
    @GetMapping("/")
    public ResultMsg<AccountDTO> get(@RequestHeader String token) {
        try {
            //从token中解析账户id
            String id = tokenManageService.getUserIdFromToken(token);
            if(StringUtils.isEmpty(id)){
                logger.error("token解析出的账户id为空，token：" + token);
                return ResultMsg.error(ResultStatusEnum.SELECT_ERROR);
            }
            //调用服务层方法获取账户，如果查询结果为空，则返回错误
            Account account = accountService.getById(id);
            if (account == null) {
                return ResultMsg.error(ResultStatusEnum.SELECT_ERROR, "无此账户");
            }
            //实体类转DTO类
            AccountDTO accountDTO = beanToDTO(account);
            //返回结果给前端
            return ResultMsg.ok(accountDTO);
        } catch (ServiceException se) {
            logger.error("获取账户失败：" + se.getMsg());
            return ResultMsg.error(ResultStatusEnum.SELECT_ERROR, se.getMsg());
        } catch (Exception e) {
            logger.error(ExceptionUtils.getStackTrace(e));
            return ResultMsg.error(ResultStatusEnum.SELECT_ERROR);
        }
    }

    /**
     * 实体类转DTO类
     * @param account
     * @return
     */
    private AccountDTO beanToDTO(Account account) {
        return ModelMapperUtils.map(account,AccountDTO.class);
    }

    /**
     * 账户实体类列表转DTO类
     * @param accountList  实体类列表
     * @return  DTO列表
     */
    private List<AccountDTO> beanListToDTOList(List<Account> accountList) {
        List<AccountDTO> dtoList = ModelMapperUtils.mapList(accountList,AccountDTO.class);
        return dtoList;
    }

}